/******************************************************************************/
/* File: tcpTrafficServer.cpp                                                 */
/******************************************************************************/

#include "tcpTrafficServer.h"

TCPTrafficServer::TCPTrafficServer(TrafficServerSetting *pSet, MessageQueue *pMQ) 
						:TCPServerSocket(pSet->bUseIPv6), pMsgQueue(pMQ) {
	cListenIP.SetHostName(pSet->sHostName, pSet->bUseIPv6);
	iListenPort = pSet->iTcpTrafficServerListenPort;
	iBackLog = pSet->iBackLog;
	bUseIPv6 = pSet->bUseIPv6;
	
	ListenServer();
}

TCPTrafficServer::~TCPTrafficServer() {
	
}

void TCPTrafficServer::CloseListenSocket() {
    CloseSocket();
}

void TCPTrafficServer::ListenServer() {
	try {
		const int iReUseAddrFlag = 1;
		SetSockOpt(SOL_SOCKET, SO_REUSEADDR, &iReUseAddrFlag, sizeof(iReUseAddrFlag));
		
		Bind(cListenIP, iListenPort);
		SetLocal();
		Listen(iBackLog);
		std::cout << "TCP traffic server is running...\n";
	} catch (SocketException se) {
		se.PrintException();
		std::cout << "Cannot start TCP traffic server.\n";
		ExitCleanUp();
		return;
	}
}

void TCPTrafficServer::UploadRegisterInfo() {
	
	RegisterRequest *ptur = new RegisterRequest();
	
	ptur->iToRegister = 1;
	ptur->iServProto = 1;
	ptur->sServIP = strdup((char *)cListenIP);
	ptur->iServPort = iListenPort;
	
	Request *pr = new Request();
	pr->iRequestType = 1;
	pr->pServerReg = ptur;
	
	Message *pm = new Message();
	pm->iMessageType = 1;
	pm->pRequest = pr;
	
	pMsgQueue->PushMessage(pm);
}

void TCPTrafficServer::UploadUnregisterInfo() {
	
	RegisterRequest *ptur = new RegisterRequest();
	
	ptur->iToRegister = 2;
	ptur->iServProto = 1;
	ptur->sServIP = strdup((char *)cListenIP);
	ptur->iServPort = iListenPort;
	
	Request *pr = new Request();
	pr->iRequestType = 1;
	pr->pServerReg = ptur;
	
	Message *pm = new Message();
	pm->iMessageType = 1;
	pm->pRequest = pr;
	
	pMsgQueue->PushMessage(pm);
}

void TCPTrafficServer::ExitCleanUp() {
	UploadUnregisterInfo();
}

void TCPTrafficServer::Run() {
	
	// Upload traffic server information.
	UploadRegisterInfo();
	
	while(true) {
		
		TCPSocket *pts;
		try {
			 pts = AcceptClient();
		}
		catch (SocketException se) {
			se.PrintException();
			ExitCleanUp();
			return;
		}

		std::cout << "Accept new TCP flow receiver instance...\n";
		
		ConnectionInfo *pci = new ConnectionInfo();
		char *cip = pts->RemoteHostName();
		char *sip = pts->LocalHostName();
		pci->sSenderIP = strdup(cip);
		pci->sRecverIP = strdup(sip);
		pci->iSenderPort = pts->RemotePortNumber();
		pci->iRecverPort = pts->LocalPortNumber();
		pci->iProto = 1; // tcp
		pci->iRole = 2;  // server

		ThreadConf *ptc = new ThreadConf();
		ptc->pFC = NULL;
		ptc->pMQ = pMsgQueue;
		
		TCPTrafficRecver *pTcpRecver = new TCPTrafficRecver(pts, ptc);
		pTcpRecver->Start(NULL);
		pTcpRecver->Detach();
		
		DataStore::AddNewFlowThread(dynamic_cast<Thread *> (pTcpRecver), pci, ptc);
	}
}

/******************************************************************************/
/* End File: tcpTrafficServer.cpp                                             */
/******************************************************************************/